home *** CD-ROM | disk | FTP | other *** search
- > Wimp.Desktop
-
- New Calls
- ---------
-
- Wimp_Initialise
- Wimp_CloseDown
- Service_WimpCloseDown
- Wimp_StartTask
-
- *Desktop
- Service_StartWimp
- Service_StartedWimp
- Wimp_Poll: reason code 18 (message) action 0 (global closedown)
-
-
- Starting/stopping a task
- ------------------------
-
- Wimp_Initialise
- Entry: if R1 = "TASK" (low-byte = "T", high-byte = "K"):
- R0 = last known Wimp version number * 100 (at least 200)
- R2 = pointer to short description of task (used by Switcher menu)
- (this is a new-style Wimp task)
- if R1 <> "TASK",
- (this is an old-style Wimp task)
- Exit: R0 = current Wimp version number * 100
- if R1 = "TASK" on entry,
- R1 = task handle on exit
-
- Old-style Wimp programs are recognised by the Wimp by the way in which they
- call Wimp_Initialise, since they won't set R1 = "TASK" (unless they are
- extremely unlucky!).
-
- When an old-style wimp application starts up, the Wimp will automatically
- open a large window with background colour 15, which covers all other
- windows, so that the task has the whole screen to itself. It will also
- prevent any other tasks from receiving any kind of event from Wimp_Poll
- while the old-style task is running.
-
- When new tasks start up, the Wimp will set up the mode and pointer (if this
- is the first task), whereas it behaves in 'compatible mode' with old tasks,
- not doing anything except programming the pointer shape.
-
-
- Wimp_CloseDown
- Entry: if R1 = "TASK",
- R0 = task handle of task to be closed down
-
- If the task handle is not specified, it is assumed to be whichever task was
- last active (ie. the last task that Wimp_Poll returned to).
-
- Note that the task handle should always be specified if Wimp_CloseDown is
- called in (eg) the 'Die' entry of a module, since the relevant task is
- probably not the one currently running.
-
- When a live task is killed using Wimp_CloseDown, the following service call is
- issued by the Wimp:
-
-
- Service_WimpCloseDown (&53)
- Entry: R0 = 0 ==> Wimp_CloseDown was called
- R0 > 0 ==> Wimp_Initialise was called in the same domain
- R2 = task handle of task being closed down
-
- Normally a task will close itself down when it has decided to finish, in
- which case the service call is somewhat superfluous, but there are two
- occasions where the task can be closed down 'automatically', as it were.
-
- The first of these happens when OS_Exit is called by the task, and
- Wimp_CloseDown has not yet been called. This can happen if, for example, an
- error is generated which is not caught by the task's own error handler - in
- this case the Wimp reports the error and calls OS_Exit automatically. The
- service call will come round with R0=0 - in this case, the task receiving
- the service call should tidy itself up, and pass on the service (it should
- NOT call Wimp_CloseDown !!!). All registers must be preserved.
-
- The second case occurs when Wimp_Initialise is called in the same task domain
- as a currently active task. This can occur, if, for example, the task allows
- the user to enter *commands, in which case it is likely that the user will
- try to start up another Wimp program. The Wimp will attempt to close down
- the first task before starting up the new one, and will send round the
- Service_WimpCloseDown with R0 > 0 (in fact R0=1 initially, but may be
- modified by the time the module receives it). If R0>0, the original task is
- allowed to return an error from the service call by pointing R0 at an error
- block (a good error message is "Wimp is currently active" (error number
- &103)). The service should not be claimed, so other modules can receive it,
- and R0 should be preserved unless an error is to be returned. If R0 > 1 on
- exit from the OS_ServiceCall, the Wimp will return the error to the task
- attempting to start up, which will prevent it from doing so. Note, however,
- that application space may well have been overwritten at this stage, so BASIC
- programs and the like cannot use this facility!
-
- Note that modules should not actually claim this service (set R1=0), since it
- is possible that more than one module is interested in a particular task
- closing down.
-
-
- Wimp_StartTask
- Entry: R0 --> *command to execute
-
- This command is used to start up a new Wimp task. It creates a new 'domain'
- for the task, and executes the *command in it. If and when the task calls
- Wimp_Initialise, and then Wimp_Poll, control will be returned to the 'parent'
- task (ie. the one which called Wimp_StartTask).
-
- Note that Wimp_StartTask cannot be called except from within a new-style Wimp
- application.
-
-
- Starting the desktop
- --------------------
-
- Either: *Desktop
- Or: Wimp is the configured language, entered by the MOS automatically
-
- The *desktop command is decoded by the Desktop module, which also supports
- the DESKFS filing system, and allows the Desktop module to be entered as a
- language. The *Desktop command cancels the current EXEC file, if any, since
- the Desktop will exit immediately if an exec file is in operation (this is so
- that SHIFT-BREAK can be used to start up a boot file).
-
- When the Desktop is entered (by either of the above methods), it attempts to
- 'wake up' any resident modules which would like to become Wimp tasks. It
- does this by passing round a service call Service_StartWimp (&49), which wimp
- application modules should respond to as follows:
-
- * if already running as a Wimp task, do nothing
- * otherwise claim the service call:
- set R0 --> *command to start up module
- R1 = 0 (claim service)
-
- The Desktop, on finding that the service call has been claimed, will pass the
- value returned in R0 on to Wimp_StartTask, thereby invoking the *command in a
- new Wimp domain.
-
- The *command should be decoded by the module (by having the command in its
- command decoding table - see PRM 'Modules' chapter), and should cause the
- module to enter itself as follows:
-
- SWI OS_Module, R0=2, R1-->module title, R2 = R0 on entry to *command
-
- (R0 points to the command tail on entry to the *command).
-
- Note that it is very important that the module starts itself up as an
- application, for the following reasons:
-
- * Wimp_Poll can only be called from USR mode
- * the Wimp intercepts the Service_NewApplication call
- * Arthur's CAO (currently active object) pointer is set up
-
- After starting up the module, the Desktop will re-issue the service call, and
- will continue in this way until no-one claims the service, at which point it
- issues Service_StartedWimp (&4A) to say that it has finished, and exits. Any
- tasks that were started up during the sequence then continue running.
-
- Example startup code:
-
- Service
- LDR R12,[R12] ; get workspace pointer
- TEQ R1,#Service_StartWimp
- MOVNE PC,LR
-
- Push "LR"
- LDR R14,mytaskhandle
- TEQ R14,#0 ; is module running?
- MOVEQ R14,#-1
- STREQ R14,mytaskhandle
- ADREQ R0,mycommand
- MOVEQ R1,#0 ; if not, claim service
- Pull "PC"
-
- mycommand
- DCB "foo",0
- ALIGN
-
- Mycommand_Code ; command table points here
- Push "LR"
- MOV R2,R0 ; R2 --> command tail
- ADR R1,ModuleTitle ; R1 --> module title
- MOV R0,#2 ; R0 = ModHandReason_Enter
- SWI XOS_Module
- Pull "PC"
-
- Note that the module must actually enter itself in this way, rather than
- simply jumping to its code, since the MOS has to flatten the supervisor stack
- and so on, as the new module is a new application.
-
-
- Errors
- ------
-
- A problem arises if any module fails to initialise properly, since after
- reporting the error to the user, the module must abort, and the Wimp will
- then re-issue the Service_StartWimp call, which will be caught again by the
- module, and so on (ie. the user is stuck in an infinite loop).
-
- It is better if any errors during initialisation are reported, followed by
- the rest of the modules starting up. To achieve this, the following
- procedure must be adopted:
-
- * When the application module is first loaded, it sets an internal
- variable called 'mytaskhandle' to zero (meaning 'not running')
-
- * When the module is entered, it should check to see if it is already
- running (mytaskhandle > 0). If it is, it should first call
- Wimp_CloseDown with R0 = mytaskhandle, R1 = "TASK", to avoid running
- as two tasks at once! Note: whenever the task closes itself down in
- this way, it should set mytaskhandle=0 afterwards.
-
- * When the module starts up successfully as a task, it calls
- Wimp_Initialise, and then sets mytaskhandle = R1 (task handle
- returned by Wimp). The value returned is defined to be greater than
- zero.
-
- * When the task terminates, the module calls Wimp_CloseDown and sets
- mytaskhandle to 0.
-
- * When the module is killed, it checks to see if mytaskhandle is
- greater than zero - if it is, it calls Wimp_CloseDown with R0 =
- mytaskhandle and R1 = "TASK" (this tells the Wimp exactly which task
- is to be closed down)
-
- * When the module receives the Service_StartWimp call, it should
- respond ONLY if mytaskhandle = 0. If it is, it should set
- mytaskhandle = -1, and return the appropriate *command from the
- service call.
-
- * If an error occurs during initialisation, the module will not attempt
- to restart, since mytaskhandle = -1. If the initialisation succeeds,
- mytaskhandle will be overwritten with the appropriate task handle
- value.
-
- * So that the user can attempt to re-run the module, the Wimp passes
- round another service call when it has finished starting up all
- dormant tasks. This is Service_StartedWimp (&4A), and when the
- module receives it it should set mytaskhandle to 0, if it was -1
- (without claiming the service).
-
- * The module should set mytaskhandle=0 when Service_Reset is detected
-
-
- Closing down
- ------------
-
- To make it easier for the user to exit from the Wimp environment, the
- switcher module provides a menu entry that allows the user to close down
- all tasks. This causes the switcher to issue a broadcast to all tasks,
- asking them to close down, which should be responded to as follows:
-
- Wimp_Poll
- Exit: R0 = 18
- R1 --> block (as supplied to Wimp_Poll)
- +0 = 20 (size of block)
- +4 = task handle of Switcher
- +8 = reference number of message
- +12 = 0
- +16 = 0 (global close down)
-
- If the task can exit immediately, it should do so (by calling Wimp_CloseDown
- followed by OS_Exit or Wimp_Poll).
-
- If the task has some unsaved data (eg. the user has modified a file and not
- saved it), it should prompt the user (in the same way as it would if the user
- had attempted to exit from the task explicitly). Before it does this,
- however, it must abort the close down sequence by acknowledging the close
- down message as follows:
-
- Wimp_SendMessage
- Entry: R0 = 19 (acknowledge message)
- R1 --> block
- + 12 = reference number of closedown message
-
- Once the user has entered a dialogue with any task in this way, therefore, he
- must explicitly restart the closedown sequence if he still wishes to quit
- from the Wimp environment.
-
-